import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_getx/app/base/refresh_indicator.dart';
import 'package:flutter_getx/app/base/state_layout.dart';
import 'package:flutter_getx/res/colors/colors.dart';
import 'package:flutter_getx/res/dimens/dimens.dart';

/// 封装下拉刷新与加载更多
class DeerListView extends StatefulWidget {

  const DeerListView({
    Key? key,
    required this.itemCount,
    required this.itemBuilder,
    this.onRefresh,
    this.loadMore,
    this.hasMore = false,
    this.stateType = StateType.empty,
    this.padding,
    this.itemExtent,
    this.shrinkWrap = false,
    this.onTapStateLayout,
    this.physics = const AlwaysScrollableScrollPhysics(),
    this.stateWidget,
    this.controller,
  }): super(key: key);

  final RefreshCallback? onRefresh;
  final LoadMoreCallback? loadMore;
  final int itemCount;
  final bool hasMore;
  final IndexedWidgetBuilder itemBuilder;
  final StateType stateType;
  /// padding属性使用时注意会破坏原有的SafeArea，需要自行计算bottom大小
  final EdgeInsetsGeometry? padding;
  final double? itemExtent;
  final bool shrinkWrap;
  final ScrollPhysics? physics;
  final GestureTapCallback? onTapStateLayout;
  final Widget? stateWidget;
  final ScrollController? controller;

  @override
  _DeerListViewState createState() => _DeerListViewState();
}

typedef RefreshCallback = Future<void> Function();
typedef LoadMoreCallback = Future<void> Function();

class _DeerListViewState extends State<DeerListView> {

  /// 是否正在加载数据
  bool _isLoading = false;
  
  @override
  Widget build(BuildContext context) {
    Widget child = widget.itemCount == 0 ?
    (widget.stateWidget ?? StateLayout(type: widget.stateType, onTap: widget.onTapStateLayout,)) :
    ListView.builder(
      controller: widget.controller,
      physics: widget.physics,
      itemCount: widget.loadMore == null ? widget.itemCount : widget.itemCount + 1,
      padding: widget.padding,
      itemExtent: widget.itemExtent,
      shrinkWrap: widget.shrinkWrap,
      itemBuilder: (BuildContext context, int index) {
        /// 不需要加载更多则不需要添加FootView
        if (widget.loadMore == null) {
          return widget.itemBuilder(context, index);
        } else {
          return index < widget.itemCount ? widget.itemBuilder(context, index) : MoreWidget(widget.hasMore);
        }
      },
    );

    if(widget.onRefresh != null) {
      child = MyRefreshIndicator(
        onRefresh: widget.onRefresh!,
        child: child,
      );
    }

    return SafeArea(
      child: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification note) {
          /// 确保是垂直方向滚动，且滑动至底部
          if (note.metrics.pixels == note.metrics.maxScrollExtent && note.metrics.axis == Axis.vertical) {
            _loadMore();
          }
          return true;
        },
        child: child,
      ),
    );
  }

  Future<void> _loadMore() async {
    if (widget.loadMore == null) {
      return;
    }
    if (_isLoading) {
      return;
    }
    if (!widget.hasMore) {
      return;
    }
    _isLoading = true;
    await widget.loadMore?.call();
    _isLoading = false;
  }

}

class MoreWidget extends StatelessWidget {
  
  const MoreWidget(this.hasMore, {Key? key}): super(key: key);

  final bool hasMore;

  final String noMoreStr = "";
  
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: hasMore ? 20.0 : (noMoreStr.isEmpty ? 20 : 20)),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          if (hasMore) const CupertinoActivityIndicator(),
          if (hasMore) SizedBox(width: Dp.dp_5,),
          /// 只有一页的时候，就不显示FooterView了
          Text(hasMore ? 'loading...' : noMoreStr, style: TextStyle(color: colorTextHint)),
        ],
      ),
    );
  }
}

